import { App, Card } from "antd";
import React, { useState, useEffect } from "react";
import { useQuery } from "@tanstack/react-query";
import SearchForm, { ISearchFormRef } from "../searchForm/index.tsx";
import { useApiRequest } from "../../hook/useApiRequest.ts";
import EChartsReact from "echarts-for-react-d8d";
import useBuildSearchFilters from "../../hook/useBuildSearchFilters.ts";
import { FormItemConfigs, TPageRequest } from "../../global.ts";
import { useQueryClient } from "@tanstack/react-query";
// API配置类型定义
export interface AdminChartApiConfig {
  search?: string;
}

export interface ChartConfig {
  type: "pie" | "bar" | "line";
  title: string;
  xField: string;
  yField: string;
  seriesField?: string;
}

interface AdminChartProps {
  searchFormFieldConfig?: FormItemConfigs[];
  apiConfig?: AdminChartApiConfig;
  chartConfig: ChartConfig;
  /** 数据，如果存在，则不请求api */
  data?: any[];
  /** 固定搜索条件 */
  fixedSearchCondition?: any;
  /** 自定义查询键 */
  queryKey?: string; 
  /** 控制搜索框显示 */
  showSearch?: boolean; 
  /** 控制组件挂载时是否提交搜索 */
  mountSubmitSearch?: boolean; 
}

const AdminChart: React.FC<AdminChartProps> = (props) => {
  const { message } = App.useApp();
  const apiConfig = props.apiConfig ?? ({} as any);
  const fixedSearchCondition = props.fixedSearchCondition ?? {};
  const searchFormRef = React.useRef<ISearchFormRef>(null);
  const queryClient = useQueryClient();
  const { requestWithToken } = useApiRequest();
  const { buildSearchFilters } = useBuildSearchFilters(props);
  const showSearch = props.showSearch ?? true; // 默认显示搜索框
  const mountSubmitSearch = props.mountSubmitSearch ?? false; // 默认不在挂载时提交
  const [manualSearchValues, setManualSearchValues] = useState<any>({});

  // 定义查询函数
  const fetchChartData = async () => {
    if (!apiConfig.search) return [];
    
    // 根据模式选择搜索值
    const searchValues = mountSubmitSearch 
      ? searchFormRef.current?.getFormValues() 
      : manualSearchValues;
    
    const combinedSearchData = {
      ...fixedSearchCondition,
      ...searchValues,
    };

    const query: TPageRequest = {
      filters: buildSearchFilters(combinedSearchData),
      pagination: {
        page: 1,
        pageSize: 1000,
      },
    };

    const result = await requestWithToken({
      url: apiConfig.search,
      method: "GET",
      data: query,
    });

    if (result.code === 200 || result.success) {
      return result.data || [];
    }
    throw new Error(result?.error || result.message);
  };

  const queryKey = [props.queryKey || 'chartData', apiConfig.search, mountSubmitSearch];

  // 使用 React Query
  const { data: chartData, isLoading, error } = useQuery<any[], Error>({
    queryKey,
    queryFn: fetchChartData,
    enabled: !!apiConfig.search,
    retry: 1,
    staleTime: 1000 * 60 * 5 // 5分钟的数据新鲜时间
  });

  // 处理错误显示
  useEffect(() => {
    if (error) {
      message.error(error.message || '获取图表数据失败');
    }
  }, [error]);

  const handleSearch = (values: any) => {
    // 保存手动搜索的值
    setManualSearchValues(values);
    // 触发重新查询
    queryClient.invalidateQueries({ queryKey });
  };

  const renderSearchForm = () => {
    return (
      <Card type="inner">
        <SearchForm
          ref={searchFormRef}
          formFieldConfig={props.searchFormFieldConfig}
          onSearch={handleSearch}
        />
      </Card>
    );
  };

  const getChartOption = (config: ChartConfig, data: any[]) => {
    const { type, title, xField, yField, seriesField } = config;

    let option: any = {
      title: { text: title },
      tooltip: { trigger: "axis" },
      legend: { data: [] },
    };

    if (type === "pie") {
      option.series = [
        {
          type: "pie",
          data: data.map((item) => ({
            name: item[xField],
            value: item[yField],
          })),
          label: {
            show: true,
            formatter: "{b}: {c} ({d}%)",
          },
        },
      ];
    } else {
      const xAxisData = Array.from(
        new Set(data.map((item) => item[xField]))
      );
      option.xAxis = {
        type: "category",
        data: xAxisData,
      };
      option.yAxis = { type: "value" };

      if (seriesField) {
        const seriesMap = new Map();
        data.forEach((item) => {
          if (!seriesMap.has(item[seriesField])) {
            seriesMap.set(
              item[seriesField],
              new Array(xAxisData.length).fill(null)
            );
          }
          const index = xAxisData.indexOf(item[xField]);
          seriesMap.get(item[seriesField])[index] = item[yField];
        });

        option.series = Array.from(seriesMap, ([name, data]) => ({
          name,
          type,
          data,
        }));
        option.legend.data = Array.from(seriesMap.keys());
      } else {
        option.series = [
          {
            type,
            data: data.map((item) => item[yField]),
          },
        ];
      }
    }

    return option;
  };

  const renderChart = () => {
    const data = props.data || chartData || [];
    return (
      <Card>
        <EChartsReact
          option={getChartOption(props.chartConfig, data)}
          style={{ height: "300px" }}
          showLoading={isLoading}
        />
      </Card>
    );
  };

  return (
    <div className="space-y-4 p-4">
      {showSearch && props.searchFormFieldConfig && (!props.data || apiConfig.search) && renderSearchForm()}
      {renderChart()}
    </div>
  );
};

export default AdminChart;
